use anyhow::Result;
use bollard::{
    image::{ImportImageOptions, RemoveImageOptions},
    Docker,
};
use futures_util::StreamExt;
use tokio::fs::File;
use tokio_util::codec;

pub async fn remove_image(docker: &Docker, image_name: &str) -> Result<()> {
    docker
        .remove_image(
            image_name,
            Some(RemoveImageOptions {
                force: true,
                ..Default::default()
            }),
            None,
        )
        .await?;

    Ok(())
}

pub async fn load_image(docker: &Docker, image: &str) -> Result<()> {
    let file = File::open(image).await?;

    let byte_stream =
        codec::FramedRead::new(file, codec::BytesCodec::new()).map(|r| r.unwrap().freeze());

    let mut stream = docker.import_image_stream(
        ImportImageOptions {
            ..Default::default()
        },
        byte_stream,
        None,
    );

    while let Some(response) = stream.next().await {
        let info = response?;
        let mut res = String::new();
        if let Some(id) = info.id {
            res.push_str(&id);
            res.push(' ');
        }
        if let Some(status) = info.status {
            res.push_str(&status);
            res.push(' ');
        }
        if let Some(progress) = info.progress {
            res.push_str(&progress);
        }

        if let Some(stream) = info.stream {
            res.push_str(&stream);
        }
        println!("{}", res);
    }

    Ok(())
}

#[cfg(test)]
mod image_tests {
    use super::*;

    #[tokio::test]
    async fn test_remove_image() {
        let docker = Docker::connect_with_unix_defaults().unwrap();
        remove_image(&docker, "redis:7.4.1").await.unwrap();
    }

    #[tokio::test]
    async fn test_load_image() {
        let docker = Docker::connect_with_unix_defaults().unwrap();
        load_image(&docker, "./images/redis.tar").await.unwrap();
    }
}
